package com.xbongbong.paas.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.MessageConstant;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.domain.entity.ext.PaasFormEntityExt;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.paas.field.DefaultAttrPoJo;
import com.xbongbong.paas.log.MongoLogHelp;
import com.xbongbong.paas.log.constant.LogMemoConstant;
import com.xbongbong.paas.model.PaasFormModel;
import com.xbongbong.paas.pojo.IdNamePojo;
import com.xbongbong.paas.pojo.IdNamePropertyPojo;
import com.xbongbong.paas.pojo.StatisticOptionPojo;
import com.xbongbong.paas.pojo.UserSimpPojo;
import com.xbongbong.paas.service.UserService;
import com.xbongbong.paas.service.WorkReportSetService;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.BeanUtil;
import com.xbongbong.paas.toolbox.util.JsonHelperUtil;
import com.xbongbong.paas.toolbox.util.StringUtil;
import com.xbongbong.paas.toolbox.wrap.BaseDTO;
import com.xbongbong.paas.toolbox.wrap.XbbResponse;
import com.xbongbong.pro.constant.SymbolConstant;
import com.xbongbong.pro.enums.DynamicManagerLevelEnum;
import com.xbongbong.pro.enums.errorcodes.WorkReportErrorCodeEnum;
import com.xbongbong.pro.enums.errorcodes.SystemErrorCodeEnum;
import com.xbongbong.pro.enums.menu.enums.OtherSetEnum;
import com.xbongbong.pro.log.pojo.DetailLogPojo;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetExplainPojo;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetFormPojo;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetUserCcPojo;
import com.xbongbong.pro.workreportset.pojo.WorkReportSetVisibleRange;
import com.xbongbong.pro.workreportset.pojo.dto.WorkReportSetDetailDTO;
import com.xbongbong.pro.workreportset.pojo.dto.WorkReportSetSaveDTO;
import com.xbongbong.pro.workreportset.pojo.vo.WorkReportSetDetailVO;
import com.xbongbong.pro.workreportset.pojo.vo.WorkReportSetFormVO;
import com.xbongbong.saas.constant.BasicConstant;
import com.xbongbong.saas.constant.StringConstant;
import com.xbongbong.saas.domain.entity.WorkReportSetEntity;
import com.xbongbong.saas.enums.DeadlineTimeEnum;
import com.xbongbong.saas.enums.OperateModuleTypeEnum;
import com.xbongbong.saas.enums.OperateTypeEnum;
import com.xbongbong.saas.enums.WorkReportDeadDayTypeEnum;
import com.xbongbong.saas.enums.XbbRefTypeEnum;
import com.xbongbong.saas.enums.business.WorkReportTypeEnum;
import com.xbongbong.saas.model.WorkReportSetModel;
import com.xbongbong.saas.service.toolbox.help.LogHelp;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.RoleEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.RoleModel;
import com.xbongbong.sys.model.UserModel;
import org.apache.commons.collections4.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * @author youli.chen
 * @ProjectName xbb-pro
 * @Description: 工作报告设置方法实现类
 * @date 2019/1/17 10:45
 */
@Service("workReportSetService")
public class WorkReportSetServiceImpl implements WorkReportSetService {
    private static final Logger LOG = LoggerFactory.getLogger(WorkReportSetServiceImpl.class);
    /**
     * 工作报告抄送人最大人数
     */
    private static final int CC_MAX_LENTH = 20;

    @Resource
    private WorkReportSetModel workReportSetModel;
    @Resource
    private RoleModel roleModel;
    @Resource
    protected DepartmentModel departmentModel;
    @Resource
    protected UserModel userModel;
    @Resource
    private UserService userService;
    @Resource
    private PaasFormModel paasFormModel;
    @Resource
    private MongoLogHelp mongoLogHelp;
    @Resource
    private LogHelp logHelp;

    /**
     * 【web】获取工作报告设置
     *
     * @param workReportSetDetailDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public XbbResponse<WorkReportSetDetailVO> workReportSet(WorkReportSetDetailDTO workReportSetDetailDTO) throws XbbException {
        String corpid = workReportSetDetailDTO.getCorpid();

        WorkReportSetDetailVO workReportSetDetailVO = new WorkReportSetDetailVO();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("type", workReportSetDetailDTO.getWorkReportType());
        param.put("corpid", corpid);
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> list = workReportSetModel.findEntitys(param);
        WorkReportSetEntity setEntity;


        List<OptionalRangeEntity> visibleObject = new ArrayList<>();
        if (list.size() >= BasicConstant.ONE) {
            setEntity = list.get(BasicConstant.ZERO);
            // 兼容，其他的del都置为1
            List<Long> ids = new ArrayList<>();
            for (WorkReportSetEntity entity : list) {
                if (Objects.equals(entity.getId(), setEntity.getId())) {
                    continue;
                }
                ids.add(entity.getId());
            }
            if (!ids.isEmpty()) {
                workReportSetModel.deleteByIdIn(ids, corpid);
            }

        } else {
            setEntity = initSetting(corpid, workReportSetDetailDTO.getUserId(), workReportSetDetailDTO.getWorkReportType());
        }
        BeanUtil.copyProperties(setEntity, workReportSetDetailVO);

        // 抄送人
        List<WorkReportSetUserCcPojo> ccUser = new ArrayList<>();
        if (setEntity.getCcUser() != null) {
            try {
                ccUser = setEntity.getCcUser().toJavaList(WorkReportSetUserCcPojo.class);
            } catch (JSONException e) {
                ccUser = new ArrayList<>();
            }
        }
        JSONArray ccUserArray = new JSONArray();
        if (!ccUser.isEmpty()) {
            for(WorkReportSetUserCcPojo ccPojo : ccUser) {
                JSONObject ccMap = new JSONObject();
                // 抄送人
                ccMap.put(BasicConstant.USERS, ccPojo.getUsers());
                ccMap.put(BasicConstant.USERS_STR,getStrWithComma(ccPojo.getUsers()));

                // 发送人所属部门
                ccMap.put(BasicConstant.EFFECTIVE_DEPS, ccPojo.getEffectiveDeps());
                ccMap.put(BasicConstant.EFFECTIVE_DEPS_STR,getStrWithComma(ccPojo.getEffectiveDeps()));
                // 批阅人
                ccMap.put(BasicConstant.APPROVED_PEOPLE,ccPojo.getApprovedPeople());
                ccMap.put(BasicConstant.APPROVED_PEOPLE_STR,getStrWithComma(ccPojo.getApprovedPeople()));
                ccUserArray.add(ccMap);
            }
        }


        workReportSetDetailVO.setCcUserApprovedPeople(ccUserArray);
        // 日报统计
        StatisticOptionPojo statisticOptionPojo = new StatisticOptionPojo();
        if (setEntity.getStatisticOption() != null) {
            try {
                statisticOptionPojo = setEntity.getStatisticOption().toJavaObject(StatisticOptionPojo.class);
            } catch (JSONException e) {
                statisticOptionPojo = new StatisticOptionPojo();
            }
        }
        workReportSetDetailVO.setStatisticOption(statisticOptionPojo);
        // 可见范围
        if (setEntity.getVisibleObject() != null) {
            try {
                visibleObject = setEntity.getVisibleObject().toJavaList(OptionalRangeEntity.class);
            } catch (JSONException e) {
                visibleObject = new ArrayList<>();
            }
        }

        // 部门、角色、员工删除，相关数据没有更新
        // 是否需要更新visible_object，如果有被删除不存在的，则需要更新
        if (visibleObject.size() > 0) {
            updateVisibleObject(setEntity, visibleObject);
        }
        PaasFormEntityExt paasFormEntityExt;
        // 日报
        if (Objects.equals(workReportSetDetailDTO.getWorkReportType(), WorkReportTypeEnum.DAILY.getType())) {
            paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(), corpid);
        } else if (Objects.equals(workReportSetDetailDTO.getWorkReportType(), WorkReportTypeEnum.WEEKLY.getType())) {
            // 周报
            paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(), corpid);
        } else {
            // 月报
            paasFormEntityExt = paasFormModel.getByBusinessType(XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode(), corpid);
        }
        if (paasFormEntityExt == null) {
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, MessageConstant.FORM_NOT_EXIST);
        }
        WorkReportSetExplainPojo workReportSetExplainPojo = new WorkReportSetExplainPojo();
        BeanUtils.copyProperties(paasFormEntityExt, workReportSetExplainPojo);
        workReportSetExplainPojo.setFormId(paasFormEntityExt.getId());
        workReportSetExplainPojo.setFormName(paasFormEntityExt.getName());
        workReportSetDetailVO.setWorkReportSetExplainPojo(workReportSetExplainPojo);
        workReportSetDetailVO.setVisibleObject(visibleObject);
        return new XbbResponse<>(workReportSetDetailVO);
    }

    /**
     * 拼接逗号
     * @param nameList
     * @return
     */
    private static String getStrWithComma(List nameList){
        if (nameList == null || nameList.size() == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (Object obj :nameList) {
            if (obj instanceof UserSimpPojo) {
                sb.append(((UserSimpPojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            } else if(obj instanceof IdNamePojo){
                sb.append(((IdNamePojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            }  else if(obj instanceof IdNamePropertyPojo){
                sb.append(((IdNamePropertyPojo)obj).getName()).append(SymbolConstant.COMMA_ENGLISH);
            } else {
                sb.append(SymbolConstant.COMMA_ENGLISH);
            }
        }
        String relatives = sb.deleteCharAt(sb.length() - 1).toString();
        return relatives;
    }

    /**
     * 【web】保存工作报告设置
     *
     * @param workReportSetSaveDTO
     * @return
     * @throws XbbException
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public XbbResponse<Integer> workReportSetSave(WorkReportSetSaveDTO workReportSetSaveDTO) throws XbbException {
        Integer successFlag = 0;
        if (workReportSetSaveDTO != null) {
            // 固定抄送人限制
            List<WorkReportSetUserCcPojo> ccUserList = workReportSetSaveDTO.getCcUserApprovedPeople();
            checkCcUser(ccUserList);
            // 截止时间类型判断
            WorkReportDeadDayTypeEnum dayTypeEnum =
                    WorkReportDeadDayTypeEnum.getByCodeType(workReportSetSaveDTO.getDeadlineOption(), workReportSetSaveDTO.getWorkReportType());
            if (dayTypeEnum == null) {
                throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207016);
            }

            String corpid = workReportSetSaveDTO.getCorpid();
            String userId = workReportSetSaveDTO.getUserId();
            Integer reportType = workReportSetSaveDTO.getWorkReportType();

            WorkReportSetEntity entity = new WorkReportSetEntity();
            WorkReportSetEntity oldEntity;
            Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
            param.put("type", reportType);
            param.put("corpid", corpid);
            param.put("del", DelEnum.NORMAL.getDel());
            List<WorkReportSetEntity> list = workReportSetModel.findEntitys(param);
            if (list.size() >= 1) {
                oldEntity = list.get(0);
            } else {
                oldEntity = initSetting(corpid, userId, reportType);
            }

            BeanUtils.copyProperties(oldEntity, entity);
            BeanUtils.copyProperties(workReportSetSaveDTO, entity);

            // 抄送人
            JSONArray ccUserArray = new JSONArray();
            if (ccUserList != null) {
                ccUserArray.addAll(ccUserList);
            }
            entity.setCcUser(ccUserArray);
            // 使用范围
            List<OptionalRangeEntity> visibleList = workReportSetSaveDTO.getVisibleObject();
            JSONArray visibleObject = new JSONArray();
            if (visibleList != null) {
                visibleObject.addAll(visibleList);
            }
            entity.setVisibleObject(visibleObject);
            // 统计指标
            StatisticOptionPojo statisticOptionPojo = workReportSetSaveDTO.getStatisticOption();
            if (statisticOptionPojo == null) {
                statisticOptionPojo = new StatisticOptionPojo();
            }
            String statisticOptionStr = JSON.toJSONString(statisticOptionPojo);
            entity.setStatisticOption(JsonHelperUtil.parseObject(statisticOptionStr));

            try {
               successFlag = workReportSetModel.update(entity);
            } catch (Exception e) {
                LOG.error("更新工作报告设置失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }

            // 登录用户名
            String loginUserName = workReportSetSaveDTO.getLoginUserName();
            // 工作报告类型名
            WorkReportTypeEnum workReportTypeEnum = WorkReportTypeEnum.getByType(reportType);

            // TODO 日志
            String memo = String.format(I18nMessageUtil.getMessage(LogMemoConstant.LOG_MEMO_UPDATE_SET), loginUserName, workReportTypeEnum.getName());
            JSONObject oldObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(oldEntity));
            JSONObject newObj = JsonHelperUtil.parseObject(JSONObject.toJSONString(entity));
            List<DetailLogPojo> detailArr = logHelp.getDetailArr4Complex(corpid, OperateModuleTypeEnum.WORKREPORT, oldObj, newObj);
            if (Objects.nonNull(detailArr)) {
                mongoLogHelp.buildLog4DetailArr(detailArr, corpid, userId, loginUserName, OperateModuleTypeEnum.WORKREPORT, OperateTypeEnum.EDIT, entity.getId().toString(), OtherSetEnum.WORK_REPORT_SETTINGS.getName(), memo, workReportSetSaveDTO.getHttpHeader());
            }

        }
        return new XbbResponse<>(successFlag);
    }

    @Override
    public WorkReportSetFormVO formList(BaseDTO baseDTO) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put(StringConstant.CORPID, baseDTO.getCorpid());
        param.put(StringConstant.DEL, DelEnum.NORMAL.getDel());
        param.put("businessTypeList", Arrays.asList(XbbRefTypeEnum.WORKREPORT_DAILY.getCode(),XbbRefTypeEnum.WORKREPORT_WEEKLY.getCode(),XbbRefTypeEnum.WORKREPORT_MONTHLY.getCode()));
        param.put("orderByStr", "business_type asc");
        List<PaasFormEntityExt> businessTypes = paasFormModel.getByBusinessTypes(param);
        List<WorkReportSetFormPojo> formPojos = new ArrayList<>();
        for (PaasFormEntityExt entityExt : businessTypes) {
            WorkReportSetFormPojo pojo = new WorkReportSetFormPojo();
            WorkReportTypeEnum byType = WorkReportTypeEnum.getByBusinessType(entityExt.getBusinessType());
            if (byType == null) {
                continue;
            }
            pojo.setWorkReportType(byType.getType());
            pojo.setAppId(entityExt.getAppId());
            pojo.setMenuId(entityExt.getMenuId());
            pojo.setFormId(entityExt.getId());
            pojo.setName(entityExt.getName());
            pojo.setBusinessType(entityExt.getBusinessType());
            formPojos.add(pojo);
        }
        WorkReportSetFormVO workReportSetFormVO = new WorkReportSetFormVO();
        workReportSetFormVO.setWorkReportSetFormPojoList(formPojos);
        return workReportSetFormVO;
    }

    @Override
    public WorkReportSetVisibleRange getVisibleRange(UserEntity userEntity) {
        return workReportSetModel.getVisibleRange(userEntity);
    }

    @Override
    public List<String> settingUsersFilter(String corpid, Integer type) {
        //是否可见
        List<String> users = new ArrayList<>();
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("type", type);
        param.put("del", DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> setEntities = workReportSetModel.findEntitys(param);
        if (setEntities != null && setEntities.size() == 1) {
            WorkReportSetEntity setEntity = setEntities.get(0);

            List<OptionalRangeEntity> visibleObject = new ArrayList<>();
            if (setEntity.getVisibleObject() != null) {
                try {
                    visibleObject = setEntity.getVisibleObject().toJavaList(OptionalRangeEntity.class);
                } catch (JSONException e) {
                    visibleObject = new ArrayList<>();
                }
            }

            //是否可见
            List<Integer> roles = new ArrayList<>();
            List<Long> userDepartmentList = new ArrayList<>();
            Boolean allDep = false;
            for (OptionalRangeEntity rangeEntity : visibleObject) {
                String property = rangeEntity.getProperty();
                String id = rangeEntity.getId();
                if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                    userDepartmentList.add(Long.parseLong(id));
                    if (Objects.equals(Long.parseLong(id), 1L)) {
                        allDep = true;
                    }
                } else if (OptionalRangeEnum.ROLE.getValue().equals(property)) {
                    roles.add(Integer.parseInt(id));
                } else if (OptionalRangeEnum.USER.getValue().equals(property)) {
                    users.add(id);
                }
            }
            Set<Long> userAllDepartmentList = new HashSet<>();

            List<DepartmentEntity> allDepartment = new ArrayList<>();
            try {
                allDepartment = departmentModel.findAllDepartment(corpid, false);
            } catch (Exception e) {
                LOG.error("settingUsersFilter error：", e);
            }
            if (allDepartment != null && allDepartment.size() > 0 && userDepartmentList.size() > 0) {
                for (Long depId : userDepartmentList) {
                    userAllDepartmentList.addAll(userService.getSubDepIdList(depId, allDepartment));
                }
            }

            //全公司
            if ((users.size() == 0 && roles.size() == 0 && userDepartmentList.size() == 0) || allDep) {
                Map<String, Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                map.put("corpid", corpid);
                map.put("del", DelEnum.NORMAL.getDel());
                return userModel.getUserIds(map);
            }
            //角色的userIds
            if (!roles.isEmpty()) {
                List<String> roleUserIds = userModel.getUserIdsByRoles(corpid, roles);
                users.addAll(roleUserIds);
            }
            //部门userIds
            if (!userDepartmentList.isEmpty()) {
                List<String> depUserIdList = userModel.getDepUserIdList(corpid, userAllDepartmentList, 0);
                users.addAll(depUserIdList);
            }
        }
        return new ArrayList<>(new HashSet<>(users));
    }

    @Override
    public DefaultAttrPoJo getCcUser(UserEntity userEntity,Integer type) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type",type);
        params.put("corpid",userEntity.getCorpid());
        params.put("del",DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetEntityList = workReportSetModel.findEntitys(params);
        if (Objects.isNull(workReportSetEntityList) || workReportSetEntityList.size() == 0){
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207022);
        }
        WorkReportSetEntity workReportSetEntity = workReportSetEntityList.get(0);
        List<Long> userDeps = JSONArray.parseArray(userEntity.getDepartment(),Long.class);
        JSONArray jsonArray = null;
        if(workReportSetEntity != null){
            jsonArray = workReportSetEntity.getCcUser();
        }
        JSONArray ccUserArray = new JSONArray();
        if(Objects.nonNull(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray effectiveDepsArray = Objects.isNull(jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS)) ? new JSONArray() : jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS);
                List<Long> depList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<IdNamePropertyPojo> depIdNameProperty = JSONArray.parseArray(effectiveDepsArray.toJSONString(),IdNamePropertyPojo.class);
                if (Objects.nonNull(depIdNameProperty) && depIdNameProperty.size() != 0){
                    for (IdNamePropertyPojo item : depIdNameProperty) {
                        depList.add(Long.valueOf(item.getId()));
                    }
                }
                // 抄送部门为空或全公司
                if (depList.isEmpty() || depList.contains(1L)) {
                    JSONArray userJson = jsonObject.getJSONArray(BasicConstant.USERS);
                    ccUserArray.addAll( Objects.isNull(userJson) ? new JSONArray() : userJson );
                } else {
                    depList.retainAll(userDeps);
                    if (depList.size()>=1) {
                        JSONArray userJson = jsonObject.getJSONArray(BasicConstant.USERS);
                        ccUserArray.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                    }
                }
            }
        }
        List<OptionalRangeEntity> defaultList = new ArrayList<>();
        DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
        defaultAttrPoJo.setDefaultType(StringConstant.CUSTOM);
        for (int i = 0; i < ccUserArray.size(); i++) {
            JSONObject ccUser = ccUserArray.getJSONObject(i);
            OptionalRangeEntity optionalRangeEntity = new OptionalRangeEntity();
            optionalRangeEntity.setProperty(OptionalRangeEnum.USER.getValue());
            optionalRangeEntity.setId(ccUser.getString(BasicConstant.ID));
            optionalRangeEntity.setName(ccUser.getString(BasicConstant.NAME));
            optionalRangeEntity.setEditable(BasicConstant.ONE);
            defaultList.add(optionalRangeEntity);
        }
        defaultAttrPoJo.setDefaultList(defaultList);
        return defaultAttrPoJo;
    }

    /**
     * 格式化explains时获取批阅人list
     * @param userEntity
     * @param type
     * @return
     */
    @Override
    public DefaultAttrPoJo getApprovedPeople(UserEntity userEntity,Integer type) throws XbbException {
        // todo
        DefaultAttrPoJo defaultAttrPoJo = new DefaultAttrPoJo();
        defaultAttrPoJo.setDefaultType(StringConstant.CUSTOM);
        List<IdNamePropertyPojo> defaultList = getApprovedPeopleList(userEntity,type);
        hasAllSupervisor(defaultList);
        if (CollectionUtils.isEmpty(defaultList)){
            defaultAttrPoJo.setDefaultValue( "所有上级主管");
        } else {
            defaultAttrPoJo.setDefaultValue( getStrWithComma(defaultList));
        }
        return defaultAttrPoJo;
    }

    @Override
    public List<IdNamePropertyPojo> getApprovedPeopleList(UserEntity userEntity, Integer type) throws XbbException {
        Map<String,Object> params = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        params.put("type",type);
        params.put("corpid",userEntity.getCorpid());
        params.put("del",DelEnum.NORMAL.getDel());
        List<WorkReportSetEntity> workReportSetEntityList = workReportSetModel.findEntitys(params);
        if (Objects.isNull(workReportSetEntityList) || workReportSetEntityList.size() == 0){
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207022);
        }
        WorkReportSetEntity workReportSetEntity = workReportSetEntityList.get(0);
        List<Long> userDeps = JSONArray.parseArray(userEntity.getDepartment(),Long.class);
        JSONArray jsonArray = null;
        if(workReportSetEntity != null){
            jsonArray = workReportSetEntity.getCcUser();
        }
        JSONArray approvedPeople = new JSONArray();
        if(Objects.nonNull(jsonArray)) {
            for (int i = 0; i < jsonArray.size(); i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                JSONArray effectiveDepsArray = Objects.isNull(jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS)) ? new JSONArray() : jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS);
                List<Long> depList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
                List<IdNamePropertyPojo> depIdNameProperty = JSONArray.parseArray(effectiveDepsArray.toJSONString(),IdNamePropertyPojo.class);
                if (Objects.nonNull(depIdNameProperty) && depIdNameProperty.size() != 0){
                    for (IdNamePropertyPojo item : depIdNameProperty) {
                        depList.add(Long.valueOf(item.getId()));
                    }
                }
                Boolean flag = true;
                for (Long depId : userDeps) {
                    if (depList.contains(depId)) {
                        flag = false;
                        break;
                    }
                }
                if (flag) {
                    continue;
                }
                // 抄送部门为空或全公司
                if (depList.isEmpty() || depList.contains(1L)) {
                    JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
                    approvedPeople.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                } else {
                    depList.retainAll(userDeps);
                    if (depList.size()>=1) {
                        JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
                        approvedPeople.addAll(Objects.isNull(userJson) ? new JSONArray() : userJson );
                    }
                }
            }
        }
        List<IdNamePropertyPojo> defaultList = new ArrayList<>();
        for (int i = 0; i < approvedPeople.size(); i++) {
            JSONObject approvedPeopleJSONObject = approvedPeople.getJSONObject(i);
            IdNamePropertyPojo optionalRangeEntity = new IdNamePropertyPojo();
            optionalRangeEntity.setProperty(approvedPeopleJSONObject.getString(BasicConstant.PROPERTY));
            optionalRangeEntity.setId(approvedPeopleJSONObject.getString(BasicConstant.ID));
            optionalRangeEntity.setName(approvedPeopleJSONObject.getString(BasicConstant.NAME));
            defaultList.add(optionalRangeEntity);
        }
        return defaultList;
    }

    /**
     * 是否要替换成 所有直属上级主管
     * @param defaultList
     * @return
     */
    private static boolean hasAllSupervisor(List<IdNamePropertyPojo> defaultList){
        boolean hasAllSupervisor = true;
        List<String> level = new ArrayList<>();
        for (int i = 0; i < defaultList.size(); i++) {
            level.add(defaultList.get(i).getName());
        }
        for (DynamicManagerLevelEnum dynamicManagerLevelEnum : DynamicManagerLevelEnum.values()){
            if (Objects.equals(dynamicManagerLevelEnum,DynamicManagerLevelEnum.ZERO_LEVEL)){
                continue;
            }
            if (!level.contains(dynamicManagerLevelEnum.getName())){
                hasAllSupervisor = false;
            }
        }
        if (hasAllSupervisor){
            Iterator iterator = defaultList.iterator();
            while (iterator.hasNext()){
                IdNamePropertyPojo idNamePropertyPojo = (IdNamePropertyPojo)iterator.next();
                if (Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.ONE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWO_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.THREE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FOUR_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FIVE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SIX_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SEVEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.EIGHT_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.NINE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.ELEVEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWELVE_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.THIRTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FOURTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.FIFTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SIXTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.SEVENTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.EIGHTEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.NINETEEN_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TWENTY_LEVEL.getName()) ||
                        Objects.equals(idNamePropertyPojo.getName(),DynamicManagerLevelEnum.TOP_LEVEL.getName())
                ){
                    iterator.remove();
                }
            }
            IdNamePropertyPojo idNamePropertyPojo = new IdNamePropertyPojo();
            idNamePropertyPojo.setId("");
            idNamePropertyPojo.setProperty("");
            idNamePropertyPojo.setName("所有上级主管");
            defaultList.add(idNamePropertyPojo);
        }
        return hasAllSupervisor;
    }

    /**
     * 新建默认的设置
     *
     * @param corpid
     * @param userId
     * @param type
     */
    @Override
    public WorkReportSetEntity initSetting(String corpid, String userId, Integer type) throws XbbException {
        WorkReportSetEntity setEntity = new WorkReportSetEntity();
        setEntity.setCorpid(corpid);
        setEntity.setCreatorUserId(userId);
        setEntity.setEditTimeLimit(-1);
        setEntity.setEnable(1);
        setEntity.setModifyUserId(userId);
        setEntity.setType(type);
        StatisticOptionPojo statisticOptionPojo = new StatisticOptionPojo();
        String statisticOptionStr = JSON.toJSONString(statisticOptionPojo);
        JSONArray ccUser = new JSONArray();
        JSONObject obj = new JSONObject();
        JSONArray jsonArray = new JSONArray();
        // 所有层级主管
        for (DynamicManagerLevelEnum cacheCode : DynamicManagerLevelEnum.values()){
            if (Objects.equals(DynamicManagerLevelEnum.ZERO_LEVEL,cacheCode)){
                continue;
            }
            JSONObject approvedPeople = new JSONObject();
            approvedPeople.put(BasicConstant.ID,cacheCode.getLevel());
            approvedPeople.put(BasicConstant.NAME,cacheCode.getName());
            approvedPeople.put(BasicConstant.PROPERTY, BasicConstant.DYNAMICMANAGER);
            jsonArray.add(approvedPeople);
        }
        obj.put(BasicConstant.APPROVED_PEOPLE,jsonArray);
        ccUser.add(obj);
        setEntity.setCcUser(ccUser);
        JSONArray visibleObject = new JSONArray();
        setEntity.setVisibleObject(visibleObject);
        setEntity.setDeadlineOption(1);
        setEntity.setDeadlineTime(DeadlineTimeEnum.DEADLINE_TIME_TWENTY_FOUR.getName());
        setEntity.setReissue(1);
        setEntity.setReissueTimeLimit(0);
        setEntity.setStatisticOption(JsonHelperUtil.parseObject(statisticOptionStr));
        try {
            workReportSetModel.insert(setEntity);
        } catch (Exception e) {
            LOG.error("初始化工作报告设置失败", e);
            throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
        }
        return setEntity;
    }

    /**
     * 获取角色数据
     *
     * @param param  参数
     * @param corpid 公司id
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-03-13 16:05
     * @version v1.0
     * @since v1.0
     */
    private List<RoleEntity> findEntitysByCorpid(Map<String, Object> param, String corpid) {
        param.put("corpid", corpid);
        List<RoleEntity> list = roleModel.findEntitys(param);
        param.put("corpid", "0");
        List<RoleEntity> sysList = roleModel.findEntitys(param);
        sysList.addAll(list);
        return sysList;
    }

    /**
     * 更新工作报告使用范围
     *
     * @param setEntity
     * @param list
     * @return
     * @throws
     * @author hongxiao
     * @date: 2019-03-12 20:52
     * @version v1.0
     * @since v1.0
     */
    private void updateVisibleObject(WorkReportSetEntity setEntity, List<OptionalRangeEntity> list) throws XbbException {
        String corpid = setEntity.getCorpid();
        boolean isUpdate = false;
        List<OptionalRangeEntity> roleList = new ArrayList<>();
        List<OptionalRangeEntity> departmentList = new ArrayList<>();
        List<OptionalRangeEntity> userList = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : list) {
            String property = rangeEntity.getProperty();
            String id = rangeEntity.getId();
            OptionalRangeEnum rangeEnum = OptionalRangeEnum.getByValue(property);
            if (rangeEnum == null || StringUtil.isEmpty(id)) {
                continue;
            }
            switch (rangeEnum) {
                case DEPT:
                    departmentList.add(rangeEntity);
                    break;
                case ROLE:
                    roleList.add(rangeEntity);
                    break;
                case USER:
                    userList.add(rangeEntity);
                    break;
                default:
                    break;
            }
        }
        // 角色
        List<OptionalRangeEntity> newRoleList = getRoleList(corpid, roleList);
        if (newRoleList.size() != roleList.size()) {
            isUpdate = true;
            roleList = newRoleList;
        }
        // 部门
        List<OptionalRangeEntity> newDepartmentList = getDepartmentList(corpid, departmentList);
        if (newDepartmentList.size() != departmentList.size()) {
            isUpdate = true;
            departmentList = newDepartmentList;
        }
        // 人员
        List<OptionalRangeEntity> newUserList = getUserList(corpid, userList);
        if (newUserList.size() != userList.size()) {
            isUpdate = true;
            userList = newUserList;
        }

        if (isUpdate) {
            JSONArray visibleArray = new JSONArray();
            list.clear();
            if (departmentList.size() > 0) {
                list.addAll(departmentList);
                visibleArray.addAll(departmentList);
            }
            if (roleList.size() > 0) {
                list.addAll(roleList);
                visibleArray.addAll(roleList);
            }
            if (userList.size() > 0) {
                list.addAll(userList);
                visibleArray.addAll(userList);
            }
            setEntity.setVisibleObject(visibleArray);
            try {
                workReportSetModel.update(setEntity);
            } catch (Exception e) {
                LOG.error("更新工作报告设置失败", e);
                throw new XbbException(SystemErrorCodeEnum.API_ERROR_100001, SystemErrorCodeEnum.API_ERROR_100001.getMsg());
            }
        }
    }

    /**
     * 获取用户角色id列表
     *
     * @param corpid   公司id
     * @param roleList 工作报告角色列表
     * @return
     */
    private List<OptionalRangeEntity> getRoleList(String corpid, List<OptionalRangeEntity> roleList) {
        List<OptionalRangeEntity> resultList = new ArrayList<>();
        if (roleList == null || roleList.size() == 0) {
            return resultList;
        }
        List<Integer> idIn = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : roleList) {
            idIn.add(Integer.parseInt(rangeEntity.getId()));
        }

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        // findEntity只查找del=0的，如果存在被删除的，则将visible_object重新赋值
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("start", 0);
        param.put("columns", "id,role_name");
        param.put("idIn", idIn);
        param.put("pageNum", idIn.size());
        param.put("corpid", corpid);
        List<RoleEntity> list = roleModel.findEntitys(param);
        if (CollectionUtils.isNotEmpty(list)){
            for (RoleEntity entity : list) {
                OptionalRangeEntity rangeEntity = new OptionalRangeEntity();
                rangeEntity.setName(entity.getRoleName());
                rangeEntity.setId(entity.getId().toString());
                rangeEntity.setEditable(1);
                rangeEntity.setProperty(OptionalRangeEnum.ROLE.getValue());
                resultList.add(rangeEntity);
            }
        }

        return resultList;
    }

    /**
     * 获取用户部门id列表
     *
     * @param corpid         公司id
     * @param departmentList 工作报告部门列表
     * @return
     */
    private List<OptionalRangeEntity> getDepartmentList(String corpid, List<OptionalRangeEntity> departmentList) {
        List<OptionalRangeEntity> resultList = new ArrayList<>();
        if (departmentList == null || departmentList.size() == 0) {
            return resultList;
        }
        List<Long> idIn = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : departmentList) {
            idIn.add(Long.parseLong(rangeEntity.getId()));
        }

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("start", 0);
        param.put("columns", "id,name");
        param.put("corpid", corpid);
        param.put("idIn", idIn);
        param.put("pageNum", idIn.size());
        List<DepartmentEntity> departList = departmentModel.findEntitys(param);
        for (DepartmentEntity entity : departList) {
            OptionalRangeEntity rangeEntity = new OptionalRangeEntity();
            rangeEntity.setName(entity.getName());
            rangeEntity.setId(entity.getId().toString());
            rangeEntity.setEditable(1);
            rangeEntity.setProperty(OptionalRangeEnum.DEPT.getValue());
            resultList.add(rangeEntity);
        }

        return resultList;
    }

    /**
     * 获取员工列表
     *
     * @param corpid   公司id
     * @param userList 工作报告员工列表
     * @return
     */
    private List<OptionalRangeEntity> getUserList(String corpid, List<OptionalRangeEntity> userList) {
        List<OptionalRangeEntity> resultList = new ArrayList<>();
        if (userList == null || userList.size() == 0) {
            return resultList;
        }

        List<String> idIn = new ArrayList<>();
        for (OptionalRangeEntity rangeEntity : userList) {
            idIn.add(rangeEntity.getId());
        }

        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("del", DelEnum.NORMAL.getDel());
        param.put("start", 0);
        param.put("columns", "corpid,user_id,name");
        param.put("corpid", corpid);
        param.put("pageNum", idIn.size());
        param.put("userIdIn", idIn);
        List<UserEntity> list = userModel.findEntitys(param);
        for (UserEntity userEntity : list) {
            OptionalRangeEntity rangeEntity = new OptionalRangeEntity();
            rangeEntity.setName(userEntity.getName());
            rangeEntity.setId(userEntity.getUserId());
            rangeEntity.setEditable(1);
            rangeEntity.setProperty(OptionalRangeEnum.USER.getValue());
            resultList.add(rangeEntity);
        }
        return resultList;
    }

    /**
     * 抄送人限制20条，且每项内部默认抄送人20人
     *
     * @param ccUserList 固定抄送人
     * @return 创建时间： 2018-4-3 上午11:04:18
     * 修改时间： 2018-4-3 上午11:04:18 chy
     * @Description: 固定抄送人格式校验
     * @author chy
     * @version v3.20
     * @since v3.20
     */
    private void checkCcUser(List<WorkReportSetUserCcPojo> ccUserList) throws XbbException {
        if (ccUserList == null) {
            return;
        }
        if (ccUserList.size() > CC_MAX_LENTH) {
            throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207004);
        }
        for (WorkReportSetUserCcPojo pojo : ccUserList) {
            List<IdNamePropertyPojo> userList = pojo.getUsers();
            if (userList != null && userList.size() > CC_MAX_LENTH) {
                throw new XbbException(WorkReportErrorCodeEnum.API_ERROR_207005);
            }
        }
    }




    /**
     * 获取当前用户应该收到的批阅人列表
     * 谁应该发送给我的报告
     * @return
     */
//    public List<String> getApprovedPeople(UserEntity userEntity, Integer type){
//        WorkReportSetEntity workReportSetEntity = workReportSetModel.getByType(type,userEntity.getCorpid());
//        JSONArray jsonArray = null;
//        if(workReportSetEntity != null){
//            jsonArray = workReportSetEntity.getCcUser();
//        }
//        if(Objects.nonNull(jsonArray)) {
//            for (int i = 0; i < jsonArray.size(); i++) {
//                JSONObject jsonObject = jsonArray.getJSONObject(i);
//                JSONArray effectiveDepsArray = Objects.isNull(jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS)) ? new JSONArray() : jsonObject.getJSONArray(BasicConstant.EFFECTIVE_DEPS);
//                List<Long> depList = new ArrayList<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
//                List<IdNamePropertyPojo> depIdNameProperty = JSONArray.parseArray(effectiveDepsArray.toJSONString(),IdNamePropertyPojo.class);
//                if (Objects.nonNull(depIdNameProperty) && depIdNameProperty.size() != 0){
//                    for (IdNamePropertyPojo item : depIdNameProperty) {
//                        depList.add(Long.valueOf(item.getId()));
//                    }
//                }
//                // 抄送部门为空或全公司
//                if (depList.isEmpty() || depList.contains(1L)) {
//                    JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
//                    approvedPeople.addAll(userJson);
//                } else {
//                    depList.retainAll(userDeps);
//                    if (depList.size()>=1) {
//                        JSONArray userJson = jsonObject.getJSONArray(BasicConstant.APPROVED_PEOPLE);
//                        approvedPeople.addAll(userJson);
//                    }
//                }
//            }
//        }
//    }
}
